# coding=utf-8

import time
import os.path

from selenium.common.exceptions import NoSuchElementException
from framework.logger import Logger
from selenium.webdriver.common.keys import Keys
# from pykeyboard import PyKeyboard

# create a logger instance
logger = Logger(logger="BasePage").getlog()


class BasePage(object):
    """
    定义一个页面基类，让所有页面都继承这个类，封装一些常用的页面操作方法到这个类
    """

    def __init__(self, driver):
        self.driver = driver

    # quit browser and end testing
    def quit_browser(self):
        self.driver.quit()

    # 浏览器前进操作
    def forward(self):
        self.driver.forward()
        logger.info("Click forward on current page.")

    # 浏览器后退操作
    def back(self):
        self.driver.back()
        logger.info("Click back on current page.")

    # 浏览器刷新页面
    def refresh(self):
        self.driver.refresh()
        logger.info("Refresh on current page.")

    # 浏览器窗口最大化
    def maxWindows(self):
        self.driver.maximize_window()

    # 隐式等待
    def wait(self, seconds):
        self.driver.implicitly_wait(seconds)
        logger.info("wait for %d seconds." % seconds)

    @staticmethod
    def sleep(seconds):
        time.sleep(seconds)
        logger.info("Sleep for %d seconds" % seconds)

    # 点击关闭当前窗口
    def close(self):
        try:
            self.driver.close()
            logger.info("Closing and quit the browser.")
        except NameError as e:
            logger.error("Failed to quit the browser with %s" % e)

    # 保存图片
    def get_windows_img(self, methodname=None):
        """
        在这里我们把file_path这个参数写死，直接保存到我们项目根目录的一个文件夹.\Screenshots下
        """
        file_path = os.path.dirname(os.path.abspath('.')) + '/screenshots/'
        rq = time.strftime('%Y%m%d%H%M', time.localtime(time.time()))
        if(None ==  methodname):
            screen_name = file_path + rq + '.png'
        else:
            screen_name = file_path + rq + '_' + methodname + '.png' # 入参添加name
        try:
            self.driver.get_screenshot_as_file(screen_name)
            logger.info("Had take screenshot and save to folder : /screenshots")
        except NameError as e:
            logger.error("Failed to take screenshot! %s" % e)
            self.get_windows_img()


    # 判断元素是否存在
    def isElementExist(self, selector):

        el = self.find_elements(selector)
        flag = False
        try:
            if len(el) != 0:
                flag = True
            return flag
            # else:
            #     raise ValueError("找到了多个元素！！！")
        except Exception as e:
            logger.error("Failed to the isElementExist with %s" % e)

    # 拆分selector
    def position_info(self, selector):

        """
         这个地方为什么是根据=>来切割字符串，请看页面里定位元素的方法
         submit_btn = "id=>su"
         login_lnk = "xpath => //*[@id='u1']/a[7]"  # 百度首页登录链接定位
         如果采用等号，结果很多xpath表达式中包含一个=，这样会造成切割不准确，影响元素定位
        :param selector:
        :return: element
        """
        try:
            position = selector.split('=>')
            if len(position) == 2:
                logger.info("%s: %s ." % (position[0], position[1]))
                return position
            else:
                raise ValueError("%s 拆分后的个数是 %d。" % (selector, len(position)))
        except Exception as e:
            logger.error("Failed to the selector splited with %s" % e)


    # 定位元素方法
    def find_element(self, selector):

        element = ''
        position = self.position_info(selector)
        if position[0] == "i" or position[0] == 'id':
            try:
                element = self.driver.find_element_by_id(position[1])
                logger.info("Had find the element \' %s \' successful "
                            "by %s via value: %s " % (element.get_attribute("tagName"), position[0], position[1]))
            except NoSuchElementException as e:
                logger.error("NoSuchElementException: %s" % e)
                self.get_windows_img()  # take screenshot

        elif position[0] == "n" or position[0] == 'name':
            try:
                element = self.driver.find_element_by_name(position[1])
                logger.info("Had find the element \' %s \' successful "
                        "by %s via value: %s " % (element.get_attribute("tagName"), position[0], position[1]))
            except NoSuchElementException as e:
                logger.error("NoSuchElementException: %s" % e)
                self.get_windows_img()  # take screenshot

        elif position[0] == "c" or position[0] == 'class_name':
            try:
                element = self.driver.find_element_by_class_name(position[1])
                logger.info("Had find the element \' %s \' successful "
                            "by %s via value: %s " % (element.get_attribute("tagName"), position[0], position[1]))
            except NoSuchElementException as e:
                logger.error("NoSuchElementException: %s" % e)
                self.get_windows_img()  # take screenshot

        elif position[0] == "l" or position[0] == 'link_text':
            try:
                element = self.driver.find_element_by_link_text(position[1])
                logger.info("Had find the element \' %s \' successful "
                            "by %s via value: %s " % (element.get_attribute("tagName"), position[0], position[1]))
            except NoSuchElementException as e:
                logger.error("NoSuchElementException: %s" % e)
                self.get_windows_img()  # take screenshot

        elif position[0] == "p" or position[0] == 'partial_link_text':
            try:
                element = self.driver.find_element_by_partial_link_text(position[1])
                logger.info("Had find the element \' %s \' successful "
                            "by %s via value: %s " % (element.get_attribute("tagName"), position[0], position[1]))
            except NoSuchElementException as e:
                logger.error("NoSuchElementException: %s" % e)
                self.get_windows_img()  # take screenshot

        elif position[0] == "t" or position[0] == 'tag_name':
            try:
                element = self.driver.find_element_by_tag_name(position[1])
                logger.info("Had find the element \' %s \' successful "
                            "by %s via value: %s " % (element.get_attribute("tagName"), position[0], position[1]))
            except NoSuchElementException as e:
                logger.error("NoSuchElementException: %s" % e)
                self.get_windows_img()  # take screenshot

        elif position[0] == "x" or position[0] == 'xpath':
            try:
                element = self.driver.find_element_by_xpath(position[1])
                logger.info("Had find the element \' %s \' successful "
                            "by %s via value: %s " % (element.get_attribute("tagName"), position[0], position[1]))
            except NoSuchElementException as e:
                logger.error("NoSuchElementException: %s" % e)
                self.get_windows_img()

        elif position[0] == "s" or position[0] == 'css_selector':
            try:
                element = self.driver.find_element_by_css_selector(position[1])
                logger.info("Had find the element \' %s \' successful "
                            "by %s via value: %s " % (element.get_attribute("tagName"), position[0], position[1]))
            except NoSuchElementException as e:
                logger.error("NoSuchElementException: %s" % e)
                self.get_windows_img()  # take screenshot
        else:
            raise NameError("Please enter a valid type of targeting elements.")

        return element


    # 批量定位元素方法
    def find_elements(self, selector):

        elements = []
        position = self.position_info(selector)
        if position[0] == "i" or position[0] == 'id':
            try:
                elements = self.driver.find_elements_by_id(position[1])
                logger.info("Had find the elements \' %s \' successful!"
                            "count is: %d " % (position[1], len(elements)))
            except NoSuchElementException as e:
                logger.error("NoSuchElementException: %s" % e)
                self.get_windows_img()  # take screenshot
        elif position[0] == "n" or position[0] == 'name':
            try:
                elements = self.driver.find_elements_by_name(position[1])
                logger.info("Had find the elements \' %s \' successful!"
                            "count is: %d " % (position[1], len(elements)))
            except NoSuchElementException as e:
                logger.error("NoSuchElementException: %s" % e)
                self.get_windows_img()  # take screenshot

        elif position[0] == "c" or position[0] == 'class_name':
            try:
                elements = self.driver.find_elements_by_class_name(position[1])
                logger.info("Had find the elements \' %s \' successful!"
                            "count is: %d " % (position[1], len(elements)))
            except NoSuchElementException as e:
                logger.error("NoSuchElementException: %s" % e)
                self.get_windows_img()  # take screenshot

        elif position[0] == "l" or position[0] == 'link_text':
            try:
                elements = self.driver.find_elements_by_link_text(position[1])
                logger.info("Had find the elements \' %s \' successful!"
                            "count is: %d " % (position[1], len(elements)))
            except NoSuchElementException as e:
                logger.error("NoSuchElementException: %s" % e)
                self.get_windows_img()  # take screenshot

        elif position[0] == "p" or position[0] == 'partial_link_text':
            try:
                elements = self.driver.find_elements_by_partial_link_text(position[1])
                logger.info("Had find the elements \' %s \' successful!"
                            "count is: %d " % (position[1], len(elements)))
            except NoSuchElementException as e:
                logger.error("NoSuchElementException: %s" % e)
                self.get_windows_img()  # take screenshot

        elif position[0] == "t" or position[0] == 'tag_name':
            try:
                elements = self.driver.find_elements_by_tag_name(position[1])
                logger.info("Had find the elements \' %s \' successful!"
                            "count is: %d " % (position[1], len(elements)))
            except NoSuchElementException as e:
                logger.error("NoSuchElementException: %s" % e)
                self.get_windows_img()  # take screenshot

        elif position[0] == "x" or position[0] == 'xpath':
            try:
                elements = self.driver.find_elements_by_xpath(position[1])
                logger.info("Had find the elements \' %s \' successful!"
                            "count is: %d " % (position[1], len(elements)))
            except NoSuchElementException as e:
                logger.error("NoSuchElementException: %s" % e)
                self.get_windows_img()  # take screenshot

        elif position[0] == "s" or position[0] == 'css_selector':
            try:
                elements = self.driver.find_elements_by_css_selector(position[1])
                logger.info("Had find the elements \' %s \' successful!"
                            "count is: %d " % (position[1], len(elements)))
            except NoSuchElementException as e:
                logger.error("NoSuchElementException: %s" % e)
                self.get_windows_img()  # take screenshot
        else:
            raise NameError("Please enter a valid type of targeting elements.")

        return elements


    # 输入
    def type(self, selector, text):

        el = self.find_element(selector)
        el.clear()
        try:
            el.send_keys(text)
            logger.info("Had type \' %s \' in inputBox" % text)

        except NameError as e:
            logger.error("Failed to type in input box with %s" % e)
            self.get_windows_img()

    # 多个元素定位输入
    def types(self, selector, text, num):

        el = self.find_elements(selector)[num]
        el.clear()
        try:
            el.send_keys(text)
            logger.info("Had type \' %s \' in inputBox" % text)
        except NameError as e:
            logger.error("Failed to type in input box with %s" % e)
            self.get_windows_img()

    #下拉框输入
    def dropDownType(self, selector, text):
        el = self.find_element(selector)
        try:
            el.send_keys(text)
            logger.info("Had type \' %s \' in Drop-down box" % text)
        except NameError as e:
            logger.error("Failed to type in Drop-down box with %s" % e)
            self.get_windows_img()

    # def config(self):
    #     #读取配置文件
    #     config = configparser.ConfigParser()
    #     file_path = os.path.dirname(os.path.abspath('.')) + '/automation_framwork_demo_1/config/config.ini'
    #     config.read(file_path)
    #     print("配置文件的文件目录" + file_path)

    # 上传文件/图片
    # def update_file(self):
    #
    #     fileName = os.path.dirname(os.path.abspath('.')) + '\\updatefile\\flie.png'
    #     k = PyKeyboard()
    #     time.sleep(1)
    #     # send_keys(Keys.SHIFT)
    #     k.tap_key(k.shift_key)#按shift切换输入法为英文
    #     k.type_string(fileName)
    #     print("路径地址："+fileName)
    #     time.sleep(2)
    #     k.tap_key(k.enter_key)
    #     time.sleep(2)

    # 双击事件,清空不行就用双击
    def double_click(self, selector):

        el = self.find_element(selector)
        try:
            el.send_keys(Keys.CONTROL+'a')
            el.send_keys(Keys.DELETE)
            logger.info("Had type \' %s \' in Drop-down box" % el.get_attribute("tagName"))
        except NameError as e:
            logger.error("Failed to type in Drop-down box with %s" % e)
            self.get_windows_img()
  

    # 清除文本框
    def clear(self, selector):

        el = self.find_element(selector)
        try:
            el.clear()
            logger.info("Clear text in input box before typing.")
        except NameError as e:
            logger.error("Failed to clear in input box with %s" % e)
            self.get_windows_img()

    # 点击元素
    def click(self,selector):

        el = self.find_element(selector)
        try:
            # 解决刷新后，界面元素无法重新定位的问题
            el_text = el.text
            el.click()
            logger.info("The element \' %s \' was clicked." % el_text)
        except NameError as e:
            logger.error("Failed to click the element with %s" % e)

    # 多个元素定位点击元素
    def clicks(self, selector, num):
        el = self.find_elements(selector)[num]
        try:
            el.click()
            logger.info("The element \' %s \' was clicked." % selector)
        except NameError as e:
            logger.error("Failed to click the element with %s" % e)

    # 获取网页标题
    def get_page_title(self):
        logger.info("Current page title is %s" % self.driver.title)
        return self.driver.title

    # 获取元素属性值
    def get_element_attribute(self, selector, element_property):

        property_info = ''
        try:
            el = self.find_element(selector)
            property_info = el.get_attribute(element_property)
            # el.__getattribute__(property)
            logger.info("the " % el.property_info)
            return property_info
        except Exception as e:
            logger.error("Failed to the get_element_attribute with: %s" % e)

    # 获取元素的标签内容
    def get_label(self, selector):

        try:
            el = self.find_element(selector)
            logger.info("The element was \' %s \' ." % el.text)
            return el.text

        except NameError as e:
            logger.error("Failed to click the element with %s" % e)

    # 多个元素定位获取元素的标签内容
    def get_labels(self, selector, num):
        el = self.find_elements(selector)[num]
        try:
            # logger.info("The element \' %s \' was clicked." % el.text)
            return el.text
        except NameError as e:
            logger.error("Failed to click the element with %s" % e)

    # 模拟键盘操作


    # 获取表格
    def get_table(self):
        table_lis = []
        try:
            row = self.driver.find_elements_by_tag_name('tr')
            for i in row:
                j = i.find_elements_by_tag_name('td')
                for item in j:
                    text = item.text
                    table_lis.append(text)
            return table_lis
        except NameError as e:
            logger.error("Failed to creat list: %s" % e)


    # 模拟键盘上的删除键操作
    def simulateBackSpace(self, selector):

        el = self.find_element(selector)
        try:
            # 解决刷新后，界面元素无法重新定位的问题
            el_text = el.text
            el.send_keys(Keys.BACK_SPACE)
            logger.info(" 'BACK_SPACE' Key was clicked in the %s." % el_text)
        except NameError as e:
            logger.error("Failed to pass the key of 'BACK_SPACE' with: %s" % e)

    # 模拟键盘上的空格键操作
    def simulateSpace(self, selector):

        el = self.find_element(selector)
        try:
            # 解决刷新后，界面元素无法重新定位的问题
            el_text = el.text
            el.send_keys(Keys.SPACE)
            logger.info(" 'SPACE' Key was clicked in the %s." % el_text)
        except NameError as e:
            logger.error("Failed to pass the key of 'SPACE' with: %s" % e)

    # 模拟键盘上的Tab键操作
    def simulateTab(self, selector):

        el = self.find_element(selector)
        try:
            # 解决刷新后，界面元素无法重新定位的问题
            el_text = el.text
            el.send_keys(Keys.TAB)
            logger.info(" 'TAB' Key was clicked in the %s." % el_text)
        except NameError as e:
            logger.error("Failed to pass the key of 'TAB' with: %s" % e)

    # 模拟键盘上的回退键操作
    def simulateEscape(self, selector):

        el = self.find_element(selector)
        try:
            # 解决刷新后，界面元素无法重新定位的问题
            el_text = el.text
            el.send_keys(Keys.ESCAPE)
            logger.info(" 'ESCAPE' Key was clicked in the %s." % el_text)
        except NameError as e:
            logger.error("Failed to pass the key of 'ESCAPE' with: %s" % e)

    # 模拟键盘上的回车键操作
    def simulateEnter(self, selector):

        el = self.find_element(selector)
        try:
            # 解决刷新后，界面元素无法重新定位的问题
            el_text = el.text
            el.send_keys(Keys.ENTER)
            logger.info(" 'ENTER' Key was clicked in the %s." % el_text)
        except NameError as e:
            logger.error("Failed to pass the key of 'ENTER' with: %s" % e)

    # 模拟键盘上的全选操作
    def simulateCtrlA(self, selector):

        el = self.find_element(selector)
        try:
            # 解决刷新后，界面元素无法重新定位的问题
            el_text = el.text
            el.send_keys(Keys.CONTROL, 'a')
            logger.info(" 'Ctrl+A' Key was clicked in the %s." % el_text)
        except NameError as e:
            logger.error("Failed to pass the key of 'Ctrl+A' with: %s" % e)

    # 模拟键盘上的复制操作
    def simulateCtrlC(self, selector):

        el = self.find_element(selector)
        try:
            # 解决刷新后，界面元素无法重新定位的问题
            el_text = el.text
            el.send_keys(Keys.CONTROL, 'c')
            logger.info(" 'Ctrl+C' Key was clicked in the %s." % el_text)
        except NameError as e:
            logger.error("Failed to pass the key of 'Ctrl+C' with: %s" % e)

    # 模拟键盘上的剪切操作
    def simulateCtrlX(self, selector):

        el = self.find_element(selector)
        try:
            # 解决刷新后，界面元素无法重新定位的问题
            el_text = el.text
            el.send_keys(Keys.CONTROL, 'x')
            logger.info(" 'Ctrl+X' Key was clicked in the %s." % el_text)
        except NameError as e:
            logger.error("Failed to pass the key of 'Ctrl+X' with: %s" % e)

    # 模拟键盘上的黏贴操作
    def simulateCtrlV(self, selector):

        el = self.find_element(selector)
        try:
            # 解决刷新后，界面元素无法重新定位的问题
            el_text = el.text
            el.send_keys(Keys.CONTROL, 'v')
            logger.info(" 'Ctrl+V' Key was clicked in the %s." % el_text)
        except NameError as e:
            logger.error("Failed to pass the key of 'Ctrl+V' with: %s" % e)

    # 模拟键盘上的F1键操作
    def simulateF1(self, selector):

        el = self.find_element(selector)
        try:
            # 解决刷新后，界面元素无法重新定位的问题
            el_text = el.text
            el.send_keys(Keys.F1)
            logger.info(" 'F1' Key was clicked in the %s." % el_text)
        except NameError as e:
            logger.error("Failed to pass the key of 'F1' with: %s" % e)
